﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Phylogeny.Dendogram;
using Candy.ViewModel;
using Candy.Web.Data;
using Microsoft.Practices.ServiceLocation;
using Candy.Model;


namespace Candy.Controls
{
    public partial class DendoCtrl : UserControl
    {
        public static readonly DependencyProperty TitleProperty;
        private string _newick;
        //public String NewickString
        //{
        //    get { return _newick; }
        //    set 
        //    {
        //        _newick = value;
        //        Show();
        //    }
        //}



        /// <summary>
        /// The <see cref="Newick" /> dependency property's name.
        /// </summary>
        public const string NewickPropertyName = "Newick";

        /// <summary>
        /// Gets or sets the value of the <see cref="Newick" />
        /// property. This is a dependency property.
        /// </summary>
        public string Newick
        {
            get
            {
                return (string)GetValue(NewickProperty);
            }
            set
            {
                SetValue(NewickProperty, value);
                Show(value);
            }
        }

        /// <summary>
        /// Identifies the <see cref="Newick" /> dependency property.
        /// </summary>
        public static readonly DependencyProperty NewickProperty = DependencyProperty.Register(
            NewickPropertyName,
            typeof(string),
            typeof(DendoCtrl),
            new PropertyMetadata(null, OnNewickChanged));

        private static void OnNewickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DendoCtrl control = (DendoCtrl)d;
            control.Show(e.NewValue as string);            
        }

        private Dendogram<GeneDto> dendo = new Dendogram<GeneDto>();

        public DendoCtrl()
        {
            InitializeComponent();
            HorizontalRadio.Checked += HorizontalRadio_Checked;
            HorizontalRadio.Unchecked += HorizontalRadio_Unchecked;
            DendoTree.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(DendoTree_SelectedItemChanged);

        }

        DendoNode<GeneDto> _selectedNode = null;
        void DendoTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (_selectedNode != null)
                _selectedNode.IsSelected = false;
            (e.NewValue as DendoNode<GeneDto>).IsSelected = true;
            _selectedNode = e.NewValue as DendoNode<GeneDto>;
            GenesViewModel gvm = ServiceLocator.Current.GetInstance<GenesViewModel>();
            if (e.NewValue != null)
                gvm.SelectGenes.Execute((e.NewValue as DendoNode<GeneDto>).Item);
            else
                gvm.SelectGenes.Execute(null);
        }

        public void Show(string newick)
        {
            try
            {

                _newick = newick;
                dendo.Prepare();
                DendoTree.ItemsSource = dendo.Tree;
                dendo.FromNewickString(_newick);
                if (dendo.Tree != null)
                {
                    IDataService dataService = ServiceLocator.Current.GetInstance<IDataService>();
                    PopulateNode(dendo.Tree, dataService.Genes.ToDictionary(x => x.Name));
                }

                ScaleSlider.DataContext = dendo.Config;
                ScaleSlider.Maximum = dendo.Config.ScaleFactor * 3;
                ToggleLabels.DataContext = dendo.Config;
            }
            catch (Exception ex)
            {

            }
        }

        private void PopulateNode(DendoNodes<GeneDto> dendoNodes, Dictionary<string, GeneDto> dict)
        {


            foreach (var node in dendoNodes)
            {
                if (node.IsLeafLabel)
                {
                    //int id;
                    //if (int.TryParse(item.Title, out id))
                    //{
                    //    if (dict.ContainsKey(id))
                    //        item.Item = dict[id];
                    //}

                    if (dict.ContainsKey(node.Title))
                        node.Item = dict[node.Title];
                    else
                    {

                    }
                }
                PopulateNode(node.SubNodes, dict);
            }
        }

        private void HorizontalRadio_Checked(object sender, RoutedEventArgs e)
        {
            Rotation.Angle = -90;
            Transformer.ApplyLayoutTransform();
        }

        private void HorizontalRadio_Unchecked(object sender, RoutedEventArgs e)
        {
            Rotation.Angle = 0;
            Transformer.ApplyLayoutTransform();
        }

        private void OnDeleteGene(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            DendoNode<GeneEditViewModel> s = b.DataContext as DendoNode<GeneEditViewModel>;

            if (GeneRemoved != null)
            {
                GeneRemovedEventArgs args = new GeneRemovedEventArgs(s.Item);
                GeneRemoved(this, args);
                if (!args.Cancel)
                    s.Item = null;
            }

        }

        public event EventHandler<GeneRemovedEventArgs> GeneRemoved;


    }

    public class GeneRemovedEventArgs : EventArgs
    {
        public GeneEditViewModel Gene { get; private set; }
        public bool Cancel { get; set; }
        public GeneRemovedEventArgs(GeneEditViewModel g)
        {
            Gene = g;
        }
    }
}
